package game.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import common.model.po.GBlueprint;
import common.model.po.GBlueprintClassification;
import common.model.request.base.PaginationRequest;
import common.model.response.base.Result;
import common.util.PageHandler;
import game.mapper.GBlueprintMapper;
import game.model.converter.GBlueprintConverter;
import game.model.request.SaveBlueprintRequest;
import game.model.request.SearchBlueprintRequest;
import game.model.vo.BlueprintVo;
import game.service.GBlueprintClassificationService;
import game.service.GBlueprintService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author 米泽鹏
 * @since 2024-08-17 下午 03:13
 */
@Service
public class GBlueprintServiceImpl extends ServiceImpl<GBlueprintMapper, GBlueprint> implements GBlueprintService {

	@Resource
	private GBlueprintMapper mapper;
	@Resource
	private GBlueprintClassificationService blueprintClassificationService;

	@Override
	public Page<BlueprintVo> searchBlueprintByPage(PaginationRequest<SearchBlueprintRequest, GBlueprint> paginationRequest) {
		Page<GBlueprint> page = paginationRequest.buildPage();
		LambdaQueryWrapper<GBlueprint> queryWrapper = paginationRequest.buildQueryWrapper().lambda();
		SearchBlueprintRequest params = paginationRequest.getParams();
		// 最低评分
		Integer minRate = params.getMinRate();
		queryWrapper.ge(minRate > 0, GBlueprint::getRate, minRate);
		// 按类别筛选
		Long classificationId = params.getClassificationId();
		if (classificationId > 0) {
			List<GBlueprintClassification> blueprintClassificationList = blueprintClassificationService.lambdaQuery().eq(GBlueprintClassification::getClassificationId, classificationId).list();
			Set<Long> blueprintIdSet = blueprintClassificationList.stream().map(GBlueprintClassification::getBlueprintId).collect(Collectors.toSet());
			if (blueprintIdSet.isEmpty()) {
				return PageHandler.convertPage(page, BlueprintVo.class);
			} else {
				queryWrapper.in(GBlueprint::getId, blueprintIdSet);
			}
		}
		// 排序方式
		Integer order = params.getOrder();
		switch (order) {
			// 最多下载
			case 1:
				queryWrapper.orderByDesc(GBlueprint::getDownloadCount);
				break;
			// 评分最高
			case 2:
				queryWrapper.orderByDesc(GBlueprint::getRate);
				break;
			// 最近上传
			case 3:
				queryWrapper.orderByDesc(GBlueprint::getBlueprintCreateTime);
				break;
			// 最近更新
			case 4:
				queryWrapper.orderByDesc(GBlueprint::getBlueprintUpdateTime);
				break;
			// 按名称排序
			case 5:
				queryWrapper.orderByAsc(GBlueprint::getBlueprintName);
				break;
			default:
				break;
		}
		queryWrapper.orderByAsc(GBlueprint::getId);
		Page<GBlueprint> resultPage = page(page, queryWrapper);
		Page<BlueprintVo> finalPage = PageHandler.convertPage(resultPage, BlueprintVo.class);
		List<BlueprintVo> blueprintVoList = finalPage.getRecords();
		if (blueprintVoList.isEmpty()) {
			return finalPage;
		}
		// 查询蓝图分类
		List<Long> blueprintIdList = blueprintVoList.stream().map(BlueprintVo::getId).collect(Collectors.toList());
		List<GBlueprintClassification> blueprintClassificationList = blueprintClassificationService.lambdaQuery().in(GBlueprintClassification::getBlueprintId, blueprintIdList).list();
		if (blueprintClassificationList.isEmpty()) {
			return finalPage;
		}
		Map<Long, List<Long>> classMapping = blueprintClassificationList.stream().collect(Collectors.groupingBy(GBlueprintClassification::getBlueprintId, Collectors.mapping(GBlueprintClassification::getClassificationId, Collectors.toList())));
		for (BlueprintVo blueprintVo : blueprintVoList) {
			blueprintVo.setClassificationIdList(classMapping.get(blueprintVo.getId()));
		}
		return finalPage;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public Result<?> saveBlueprint(SaveBlueprintRequest request) {
		GBlueprint po = GBlueprintConverter.saveRequestToPo(request);
		List<Long> classificationIdList = request.getClassificationIdList();
		if (request.getId() == null) {
			// 新增蓝图
			save(po);
		} else {
			// 更新蓝图
			updateById(po);
			// 删除现有的蓝图-类别的关联关系
			blueprintClassificationService.lambdaUpdate().eq(GBlueprintClassification::getBlueprintId, request.getId()).remove();
		}
		// 新增蓝图-类别的关联关系
		if (CollUtil.isNotEmpty(classificationIdList)) {
			List<GBlueprintClassification> blueprintClassificationList = Lists.newArrayList();
			for (Long classificationId : classificationIdList) {
				GBlueprintClassification blueprintClassification = new GBlueprintClassification();
				blueprintClassification.setBlueprintId(po.getId());
				blueprintClassification.setClassificationId(classificationId);
				blueprintClassification.setSort(0);
				blueprintClassificationList.add(blueprintClassification);
			}
			blueprintClassificationService.saveBatch(blueprintClassificationList);
		}
		return Result.success();
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public Result<?> deleteBlueprint(Long id) {
		// 删除蓝图
		removeById(id);
		// 删除蓝图和类别的关联关系
		blueprintClassificationService.remove(new LambdaQueryWrapper<GBlueprintClassification>().eq(GBlueprintClassification::getBlueprintId, id));
		return Result.success();
	}

}
